%% Created Time:  Sun Apr 22 10:34:27 2012

-module(main).
-export([start/0, stop/0, parallel/0, par_c/1, seq/0, seq_loop/1, process/1]).
-author("Charon <kevinlpcd@gmail.com>").
-vsn("main 0.1").
-define(TRACE(X), io:format("TRACE ~p:~p ~p. [@~p]~n", [?MODULE, ?LINE, X, ?FILE])).
-define(Port,6012).
-define(TCP_OPTION, [binary, {packet, 0},{active, false},{reuseaddr, true}]).

start() ->
	gain:start(),
	case gen_tcp:listen(?Port, ?TCP_OPTION) of
		{ok, Listen} ->
			server_loop(Listen);
		{error, Reason} ->
			exit({listen, Reason})
	end.


seq() ->
	gain:start(),
	{ok, Listen} = gen_tcp:listen(?Port, ?TCP_OPTION),
	seq_loop(Listen).

seq_loop(Listen) ->
	{ok, Socket} = gen_tcp:accept(Listen),
	process(Socket),
	seq_loop(Listen).

parallel() ->
	gain:start(),
	{ok, Listen} = gen_tcp:listen(?Port, ?TCP_OPTION),
	spawn(fun() -> par_c(Listen) end).

par_c(Listen) ->
	{ok, Socket} = gen_tcp:accept(Listen),
	spawn(fun() -> par_c(Listen) end),
	process(Socket).

server_loop(Listen) ->
	case gen_tcp:accept(Listen) of
		{ok, Socket} ->
			spawn(?MODULE, process, [Socket]),
			server_loop(Listen);
		{error, Reason} ->
			exit({accept, Reason})
	end.

process(Socket) ->
	io:format("I come~n"),
	Request = do_reveive(Socket),
	io:format("io:~p~n",[Request]),
	Ts = re:split(Request, "[ \r\n]"),
	[Method | [URL | [Version | [ _ | [ _ | [Host | O_Header]]]]]] = Ts,
	?TRACE(Request),
	Me = list_to_atom(string:to_lower(binary_to_list(Method))),
	?TRACE(URL),
	case Me of
		get ->
			?TRACE(Me),
			FormatHeader = gain:headerParse(Request, Me),
			All = gain:get_url_s(binary_to_list(URL), Me, FormatHeader, all),
			F_ret = gain:retCombine(All);
		post ->
			{FormatHeaderP, PostData} = gain:headerParse(Request, Me),
			?TRACE(PostData),
			All_P = gain:get_url_s(binary_to_list(URL), Me, {FormatHeaderP,PostData}, all),
			?TRACE(All_P),
			F_ret = gain:retCombine(All_P)

	end,
	?TRACE(F_ret),
	do_send(Socket, F_ret),
	gen_tcp:close(Socket).

do_send(Socket, Message) ->
	case gen_tcp:send(Socket, list_to_binary(Message)) of
		ok -> ok;
		{error, Reason} -> exit(Reason)
	end.

do_reveive(Socket) ->
	case gen_tcp:recv(Socket, 0) of
		{ok, Bin} -> binary_to_list(Bin);
		{error, closed} -> exit(closed);
		{error, Reason} -> exit(Reason)
	end.
stop() ->
	gain:stop().
